package com.rf.richfitwheel.workflow.cmd;


import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.rf.richfitwheel.workflow.model.WfProcessTransfer;
import com.rf.richfitwheel.workflow.service.WfProcessTransferService;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.impl.cmd.AddCommentCmd;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ExecutionEntityManager;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.pvm.PvmException;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.activiti.engine.impl.pvm.runtime.InterpretableExecution;


public class JumpTaskCmd implements Command<Void> {

    protected String taskId;//任务id
    protected String executionId;//执行实例id
    protected ActivityImpl targetActivity;//目标节点
    private String approveMessage;
    private String approveAdvice;
    protected Map<String, Object> variables;//变量
    protected ActivityImpl nowActivity;//当前的节点
    WfProcessTransferService wfProcessTransferService;

    @Override
    public Void execute(CommandContext commandContext) {
        WfProcessTransfer wfProcessTransfer = new WfProcessTransfer();
        ExecutionEntityManager executionEntityManager = Context
                .getCommandContext().getExecutionEntityManager();
        ExecutionEntity executionEntity = executionEntityManager
                .findExecutionById(executionId);
        //寻找根路径
        String id = executionEntity.getProcessInstanceId();
        //设置相关变量
        executionEntity.setVariables(variables);
        //executionEntity.setExecutions(null);
        executionEntity.setEventSource(this.nowActivity);
        executionEntity.setActivity(this.nowActivity);
        // 根据executionId 获取Task
        Iterator<TaskEntity> localIterator = Context.getCommandContext()
                .getTaskEntityManager().findTasksByProcessInstanceId(id).iterator();
        //删除无用的工作项
        while (localIterator.hasNext()) {
            TaskEntity taskEntity = (TaskEntity) localIterator.next();
            System.err.println("==================" + taskEntity.getId());
            if (taskId.equals(taskEntity.getId())) {
                wfProcessTransfer.setActId(taskEntity.getTaskDefinitionKey());
                wfProcessTransfer.setExecId(taskEntity.getExecutionId());
                wfProcessTransfer.setParExecId(id);
                wfProcessTransfer.setParParExecId("");
                wfProcessTransfer.setFormUser(taskEntity.getAssignee());
                wfProcessTransfer.setTaskType(this.getTaskType(nowActivity));
                wfProcessTransfer.setProcInstId(taskEntity.getProcessInstanceId());
                wfProcessTransfer.setTaskId(taskEntity.getId());
                wfProcessTransfer.setToActId(targetActivity.getId());
                wfProcessTransferService.save(wfProcessTransfer);
                AddCommentCmd addCommentCmd = new AddCommentCmd(taskId, taskEntity.getProcessInstanceId(), this.approveMessage);
                addCommentCmd.execute(commandContext);
                // 触发任务监听
                taskEntity.fireEvent("complete");
                taskEntity.setDescription(this.approveAdvice);
                // 删除任务的原因
                Context.getCommandContext().getTaskEntityManager().deleteTask(taskEntity, "completed", false);
            } else {
                // 删除任务的原因
                Context.getCommandContext().getTaskEntityManager().deleteTask(taskEntity, "deleted", false);
            }

        }
        //删除相关执行子路径，只保留根执行路径
        List<ExecutionEntity> list = executionEntityManager.findChildExecutionsByParentExecutionId(id);
        for (ExecutionEntity executionEntity2 : list) {
            ExecutionEntity findExecutionById = executionEntityManager.findExecutionById(executionEntity2.getId());

            List<ExecutionEntity> parent = executionEntityManager
                    .findChildExecutionsByParentExecutionId(executionEntity2.getId());
            for (ExecutionEntity executionEntity3 : parent) {
                executionEntity3.remove();
                System.err.println(executionEntity3.getId()
                        + "----------------->>>>>>>>>>");
                Context.getCommandContext().getHistoryManager().recordActivityEnd(executionEntity3);

            }

            executionEntity2.remove();
            Context.getCommandContext().getHistoryManager().recordActivityEnd(executionEntity2);
            System.err.println(findExecutionById + "----------------->>>>>>>>>>");
        }

        commandContext.getIdentityLinkEntityManager().deleteIdentityLinksByProcInstance(id);
        //要激活交路径
        executionEntity.setActive(true);
        //去掉无用的变量，不去掉，会导致很多莫名奇妙的问题
        executionEntity.removeVariable("loopCounter");
        //去掉多实例的变量，如果变量不知道是啥，自己从节点定义里查
        executionEntity.removeVariable("cdp_atuser");
        //触发事件监听器
        this.execute(executionEntity);
        InterpretableExecution propagatingExecution = null;
        if (this.targetActivity.isScope()) {
            propagatingExecution = (InterpretableExecution) executionEntity.createExecution();
            executionEntity.setTransition(null);
            executionEntity.setActivity(null);
            executionEntity.setActive(false);
            // log.debug("create scope: parent {} continues as execution {}", execution, propagatingExecution);
            propagatingExecution.initialize();
        } else {
            propagatingExecution = executionEntity;
        }
        propagatingExecution.executeActivity(this.targetActivity);
        return null;
    }


    protected ScopeImpl getScope(InterpretableExecution execution) {
        return (ScopeImpl) execution.getActivity();
    }

    public String getTaskType(ActivityImpl activity) {
        String taskType = activity.getProperty("type").toString();
        if (activity.getProperties().containsKey("multiInstance")) {
            taskType = activity.getProperty("multiInstance").toString();
        }
        return taskType;
    }

    /*
      触发事件监听器
     */
    public void execute(InterpretableExecution execution) {
        ScopeImpl scope = getScope(execution);
        List<ExecutionListener> exectionListeners = scope.getExecutionListeners(getEventName());
        for (ExecutionListener listener : exectionListeners) {
            execution.setEventName(getEventName());
            execution.setEventSource(scope);
            try {
                listener.notify(execution);
            } catch (RuntimeException e) {
                throw e;
            } catch (Exception e) {
                throw new PvmException("couldn't execute event listener : " + e.getMessage(), e);
            }

        }
    }

    protected String getEventName() {
        return org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_END;
    }

    /**
     * 构造参数 可以根据自己的业务需要添加更多的字段
     *
     * @param wfProcessTransferService
     * @param taskId
     * @param executionId
     * @param targetActivity
     * @param variables
     * @param nowActivity
     */
    public JumpTaskCmd(WfProcessTransferService wfProcessTransferService,
                       String taskId,
                       String executionId,
                       ActivityImpl nowActivity,
                       ActivityImpl targetActivity,
                       String approveMessage,
                       String approveAdvice,
                       Map<String, Object> variables) {
        this.wfProcessTransferService = wfProcessTransferService;
        this.taskId = taskId;
        this.executionId = executionId;
        this.nowActivity = nowActivity;
        this.targetActivity = targetActivity;
        this.approveMessage = approveMessage;
        this.approveAdvice = approveAdvice;
        this.variables = variables;
    }
}
